<?php
namespace app\custom\service;

use app\common\library\Service;
use think\Db;

class Custom extends Service
{
    use \app\common\library\traits\Model;

    // 模型验证
    protected $modelValidate = null;
    // 批量验证
    protected $batchValidate = null;

    protected function _initialize() {
        parent::_initialize();
        $this->model = model('custom/custom');
    }

    /**
     * 客户列表
     * @param mixed $maps   查询条件
     * @return mixed
     */
    public function lists($maps = '', $order = 'create_time DESC', $page = 0, $limit = 12, $field = true, $relations = [], $attrs =[]) {
        $result = $this->model->order($order)->field($field);
        if (isset($maps['id'])) {
            $result = $result->where('id','=',$maps['id']);
        }
        if (!empty($maps['username'])){
            $result = $result->where('username','like','%'.$maps['username'].'%');
        }
        if (!empty($maps['mobile'])){
            $result = $result->where('mobile','like','%'.$maps['mobile'].'%');
        }
        if (!empty($maps['email'])){
            $result = $result->where('email','like','%'.$maps['email'].'%');
        }
        if (isset($maps['current_id'])) {
            $result = $result->where('current_id','=',$maps['current_id']);
        }
        if (isset($maps['parent_current_id'])) {
            $result = $result->where('parent_current_id','=',$maps['parent_current_id']);
        }
        if (isset($maps['status'])) {
            $result = $result->where('status','=',$maps['status']);
        }
        if (!empty($maps['type']) && !empty($maps['keywords'])){
            $result = $result->where($maps['type'],'like','%'.$maps['keywords'].'%');
        }

        if($page !== false) {
            $result = $result->paginate($limit, '', ['page' => $page]);
        } else {
            if ($limit > 0) {
                $result = $result->limit($limit);
            } else {
                $result = $result->select();
            }
        }

        /* 关联数据获取 */
        if(!empty($relations)) {
            foreach ($result as $key => $value) {
                array_map(function($e) use (&$value) {
                    $e = trim($e);
                    $value->$e = $value->$e ?: new \stdClass(); // 注意没有数据不要返回默认的 NULL
                }, $relations);
            }
        }

        /* 获取器数据 */
        if(!empty($attrs)) {
            foreach ($result as $key => $value) {
                array_map(function($attr) use (&$value) {
                    $attr = trim($attr);
                    return $value->$attr = $value->getAttr($attr);
                }, $attrs);
            }
        }
        return $result;
    }

    /**
     * 详情
     * @param [array]   $maps       [查询条件]
     * @param [string]  $field      [查询字段]
     * @param [array]   $relations  [关联数据]
     * @param [array]   $attrs      [获取器数据]
     * return mix
     */
    public function detail($maps = '',$field = true,$relations = [],$attrs = []){
        $model = model('custom/custom');
        if (!empty($maps['id'])){
            $model = $model->where('id', '=', $maps['id']);
        }
        if (!empty($maps['current_id'])) {
            $model = $model->where('current_id', '=', $maps['current_id']);
        }

        $result = $model->field($field)->relation($relations)->find();
        if (!$result) {
            $this->error = '客户不存在';
            return false;
        }

        /* 获取器数据 */
        if(!empty($attrs)) {
            array_map(function($attr) use (&$result) {
                $attr = trim($attr);
                return $result->$attr = $result->getAttr($attr);
            }, $attrs);
        }
        return $result;
    }

    /**
     * 创建客户
     * @param array $data 客户信息
     * @return mixed
     */
    public function create($data = []) {
        $model = model('custom/custom');
        if (!isset($data) || empty($data)) {
            $this->error = '客户信息不能为空';
            return false;
        }
        $mobile = $this->model->where('mobile','=',$data['mobile'])->find();
        if (!empty($mobile->id)){
            $this->error = '手机号已存在';
            return false;
        }
        $data['current_id'] = $this->_build_current_id();
        $data['parent_current_id'] = !empty($data['parent_current_id']) ? $data['parent_current_id'] : '';
        $data['salt'] = \fast\Random::nozero(6);
        $data['password'] = md5(md5($data['password']).$data['salt']);
        $data['last_login_time'] = 0;
        Db::startTrans();
        try{
            $model->isUpdate(false)->save($data);
            //同步设置客户网站信息
            $setting_info = [];
            $setting_info['current_id'] = $data['current_id'];
            $setting_info['name']  = $data['username'].'的客户系统';
            $setting_info['title'] = $data['username'].'的客户系统';
            $set_result = model('custom/custom_setting', 'service')->setting($setting_info);
            if ($set_result === false) {
                throw new \Exception(model('custom/custom_setting', 'service')->getError());
            }
        } catch (\Exception $e) {
            Db::rollback();
            $this->error = $e->getMessage();
            return false;
        }
        Db::commit();
        return $model;
    }

    /**
     * 编辑
     * @param array  $data        客户信息
     * @param string $current_id  客户标识
     * @return mixed
     */
    public function save($data = [], $current_id = '') {
        if (empty($data)) {
            $this->error = '客户信息不能为空';
            return false;
        }
        $custom = $this->model->where('current_id','=',$current_id)->find();
        if (empty($custom->id)) {
            $this->error = '客户不存在';
            return false;
        }
        if (isset($data['mobile'])){
            $mobile = $this->model->where('current_id','neq',$current_id)->where('mobile','=',$data['mobile'])->find();
            if (!empty($mobile->id)){
                $this->error = '手机号已存在';
                return false;
            }
        }
        if (isset($data['password'])){
            if ($custom->password === $data['password']){
                unset($data['password']);
            }else{
                $data['password'] = md5(md5($data['password']).$custom->salt);
            }
        }
        Db::startTrans();
        try {
            $custom->isUpdate(true)->save($data);
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            Db::rollback();
            return false;
        }
        Db::commit();
        return $custom;
    }

    /**
     * 充值
     * @param string  $current_id  充值账户标识
     * @param string  $money       充值金额
     * @param string  $remark      充值备注
     * @param string  $parent_current_id  父级充值账户标识
     * @return mixed
     */
    public function recharge($current_id = '',$money = '0.00',$remark = '',$parent_current_id = ''){
        $custom = $this->model->where('current_id','=',$current_id)->find();
        if (empty($custom->id)) {
            $this->error = '要充值的客户不存在';
            return false;
        }
        if ($parent_current_id != $custom->parent_current_id){
            $this->error = '非法操作，请联系管理员';
            return false;
        }
        //最低充值金额
        $low_recharge_money = \app\admin\model\Config::where('key','=','low_recharge_money')->value('value');
        if ($money < $low_recharge_money){
            $this->error = '最低充值金额不能小于'.$low_recharge_money.'元';
            return false;
        }
        
        Db::startTrans();
        try {
            //充值
            $custom->balance = $custom->balance + (float) $money;
            $custom->isUpdate(true)->save();
            //写入充值日志
            $log = [];
            $log['current_id'] = $current_id;
            $log['type'] = 'recharge';
            $log['money'] = $money;
            $log['remark'] = $remark;
            $log['desc'] = $custom->username.'于'.date('Y-m-d H:i:s',time()).'充值金额：'.$money.'元，充值后余额：'.$custom->balance.'元';
            $log_result = model('custom/custom_fee')->create($log);
            if (!$log_result){
                throw new \Exception(model('custom/custom_fee')->getError());
            }
            //充值扣费
            if (!empty($parent_current_id)){
                $result = $this->deduction($parent_current_id,$money,'充值扣费');
                if ($result === false){
                    throw new \Exception($this->error);
                }
            }
            //充值后置钩子
            \Hook::listen("soCustomRechargeAfter", $custom);
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            Db::rollback();
            return false;
        }

        Db::commit();
        return $custom;
    }

    /**
     * 扣费
     * @param string  $current_id  扣费账户标识
     * @param string  $money       扣除金额
     * @param string  $remark      扣费备注
     * @return mixed
     */
    public function deduction($current_id = '',$money = '0.00',$remark = ''){
        $custom = $this->model->where('current_id','=',$current_id)->find();
        if (empty($custom->id)){
            $this->error = '账户不存在';
            return false;
        }
        if ($custom->balance < $money){
            $this->error = '账户余额不足';
            return false;
        }
        Db::startTrans();
        try {
            //扣费
            $custom->balance = $custom->balance - (float) $money;
            $custom->isUpdate(true)->save();
            //写入扣费日志
            $log = [];
            $log['current_id'] = $current_id;
            $log['type'] = 'deduction';
            $log['money'] = $money;
            $log['remark'] = $remark;
            $log['desc'] = $custom->username.'于'.date('Y-m-d H:i:s',time()).'消费金额：'.$money.'元，消费后余额：'.$custom->balance.'元';
            $log_result = model('custom/custom_fee')->create($log);
            if (!$log_result){
                throw new \Exception(model('custom/custom_fee')->getError());
            }
            //扣费后置钩子
            \Hook::listen("soCustomDeductionAfter", $custom);
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            Db::rollback();
            return false;
        }

        Db::commit();
        $custom->log_id = $log_result['id'];
        return $custom;
    }


    /**
     * 登录
     * @param string  $data[username]  用户名
     * @param string  $data[password]  登陆密码
     * @return mixed
     */
    public function login($data = []){
        $custom = $this->model->where(['username' => $data['username']])->find();
        if(empty($custom->id)) {
            $this->error = '用户名或密码错误';
            return false;
        }
        if($custom['password'] !== md5(md5($data['password']).$custom['salt'])){
            $this->error = '用户名或密码错误!';
            return false;
        }
        if ($custom->status == -1){
            $this->error = '当前账户已被禁用，请联系管理员!';
            return false;
        }
        Db::startTrans();
        try {
            $custom->login_ip = request()->ip();
            $custom->last_login_time = time();
            $custom->isUpdate(true)->save();
            //写入登陆cookie
            cookie('account_token',encrypt($custom->username."_\t".$custom->password));
            //登陆后置钩子
            \Hook::listen("soCustomLoginAfter", $custom);
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            Db::rollback();
            return false;
        }

        Db::commit();
        return $custom;
    }

    /**
     * 登录验证
     * @param string  $account_token  用户token
     * @return mixed
     */
    public function validate_token($account_token = ''){
        if (empty($account_token)){
            $this->error = 'token不能为空';
            return false;
        }
        $account_token = decrypt($account_token);
        list($username, $password) = explode("_\t", $account_token);
        $custom = $this->model->where('username','=',$username)->where('password','=',$password)->find();
        if (empty($custom->id)){
            $this->error = '非法登陆';
            return false;
        }
        return $custom;

    }

    /**
     * 忘记密码
     * @param string  $data[mobile]     手机号
     * @param string  $data[password]   新密码
     * @return mixed
     */
    public function forget($data = []){
        $custom = $this->model->where('mobile','=',$data['mobile'])->find();
        if (empty($custom->id)){
            $this->error = '未找到该用户!';
            return false;
        }
        Db::startTrans();
        try {
            $custom->salt = \fast\Random::nozero(6);
            $custom->password = md5(md5($data['password']).$custom->salt);
            $custom->isUpdate(true)->save();
            //写入登陆cookie
            cookie('account_token',encrypt($custom->username."_\t".$custom->password));
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            Db::rollback();
            return false;
        }

        Db::commit();
        return $custom;
    }

    /**
     * 修改密码
     * @param string  $current_id  客户标识
     * @param string  $oldpassword 旧密码
     * @param string  $password    新密码
     * @return mixed
     */
    public function edit_password($current_id = '',$oldpassword = '',$password = ''){
        $custom = $this->model->where('current_id','=',$current_id)->find();
        if(empty($custom)){
            $this->error = '未找到客户!';
            return false;
        }
        $oldpassword = md5(md5($oldpassword).$custom['salt']);
        if($oldpassword != $custom['password']){
            $this->error = '原密码错误!';
            return false;
        }
        Db::startTrans();
        try {
            $custom->salt = \fast\Random::nozero(6);
            $custom->password = md5(md5($password).$custom->salt);
            $custom->isUpdate(true)->save();
            //写入登陆cookie
            cookie('account_token',encrypt($custom->username."_\t".$custom->password));
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            Db::rollback();
            return false;
        }
        Db::commit();
        return $custom;
    }

    /**
     * 软删除
     * @param string $current_id 客户标识
     * @return mixed
     */
    public function destroy($current_id = '') {
        if (empty($current_id)) {
            $this->error = '要删除的客户不能为空';
            return false;
        }
        $info = $this->model->where('current_id','=',$current_id)->find();
        if (!$info) {
            $this->error = '要删除的客户不存在';
            return false;
        }
        Db::startTrans();
        try {
            $info->destroy(['current_id'=>$current_id]);
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            Db::rollback();
            return false;
        }
        Db::commit();
        return $info;
    }

    /**
     * 生成六位唯一账号标识
     * @return string
     */
    private function _build_current_id() {
        $code = \fast\Random::alnum(6);
        $custom = $this->model->where('current_id','=',$code)->find();
        if (!empty($custom->id)){
            self::_build_current_id();
        }
        return $code;
    }
}